package helpers
{
	import flash.display.DisplayObject;
	import flash.errors.IllegalOperationError;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	import org.osflash.signals.natives.NativeSignal;
	
	/**
	 * ...
	 * @author Ja
	 */
	public class InputController
	{
		private var _nativeSignal:NativeSignal;
		
		private var _target:IEventDispatcher
		
		private static var _targets:Dictionary = new Dictionary(true);
		private static var _nativeSignals:Dictionary = new Dictionary(true);
		
		private var _eventType:String = "";
		private var _eventClass:Class = null;
		
		private static var _inputController:InputController;
		
		public function InputController(privateClass:PrivateClass = null, eventType:String = "click", eventClass:Class = null)
		{
			if (!privateClass)
				throw new IllegalOperationError("use method InputController.getInstance()");
			
			_eventType = eventType;
			_eventClass = eventClass;
		
		}
		
		public static function getInstance(eventType:String = "click", eventClass:Class = null):InputController
		{
			if (_inputController == null)
			{
				
				return new InputController(new PrivateClass(), eventType, eventClass);
			}
			
			return _inputController;
		}
		
		public function addSignal(target:DisplayObject, listener:Function = null, eventType:String = "", eventClass:Class = null):void
		{
			//set different eventType and class if need
			if (eventType != "")
			{
				_eventType = eventType;
				_eventClass = eventClass;
				
			}
			//add new target if doesnt exist
			if (InputController._targets[target] == undefined)
			{
				_targets[target] = target;
					//trace(_targets[target])
			}
			//add new signal if doesnt exist
			if (_nativeSignals[target.name + _eventType] == undefined)
			{
				//var signal:NativeSignal = new NativeSignal(target, _eventType, _eventClass);
				_nativeSignals[target.name + _eventType] = new NativeSignal(target, _eventType, _eventClass);
					//trace(_nativeSignals[target.name+_eventType])
			}
			
			//add function handler if asked
			if (listener != null)
			{
				
				//add new listener to existing signal
				_nativeSignals[target.name + _eventType].add(listener);
					//trace(_targets[target], "added new function");
				
			}
		
		}
		
		public function unregisterFunctionFrom(target:DisplayObject, eventType:String, listener:Function):void
		{
			if (_nativeSignals[target.name + eventType])
			{
				
				_nativeSignals[target.name + eventType].remove(listener);
			}
			else
			{
				trace("signal undefined, cant remove function")
				return;
			}
		
		}
		
		public function unregisterAllFrom(target:DisplayObject, disposeSignal:Boolean = false):void
		{
			for (var name:String in _nativeSignals)
			{
				
				if (_nativeSignals[name].target == target)
				{
					_nativeSignals[name].removeAll();
					if (disposeSignal)
					{
						_nativeSignals[name] = null;
						delete _nativeSignals[name];
						
					}
				}
			}
		
		
		}
		
		public function disposeAll():void
		{
			for each (var target:DisplayObject in _targets)
			{
				unregisterAllFrom(target, true);
				target = null;
				delete _targets[target];
				
			}
		
		}
		
		static public function get targets():Dictionary
		{
			return _targets;
		}
		
		public function get nativeSignal():NativeSignal
		{
			if (_nativeSignal)
			{
				return _nativeSignal;
			}
			else
			{
				trace("add at least 1 signal")
				return null
			}
		
		}
		
		static public function get nativeSignals():Dictionary
		{
			return _nativeSignals;
		}
		
		public function getNativeSignal(fromTarget:DisplayObject):NativeSignal
		{
			for (var name:String in _nativeSignals) 
			{
				if (_nativeSignals[name].target == fromTarget)
				{
					trace(_nativeSignals[name].target);
					return _nativeSignals[name];
				}
				else
				{
					return null;
				}
			}
			return null;
			
		}
	
	}

}

class PrivateClass
{
	public function PrivateClass():void
	{
	
	}
}